home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk157 / lockdevice / lockdevice.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  13KB  |  641 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by MXM
  4.  *
  5.  *    Name .....: LockDevice-Handler.c
  6.  *    Created ..: Tuesday 26-Jun-90 14:19
  7.  *    Revision .: 1
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    26-Jun-90       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15.     /* Arp cli arguments. */
  16.  
  17. char *CLI_Template    = "Drive,L=Lock/K,K=Key/K,S=Show/S,Info/S,Q=Quit/S";
  18. char *CLI_Help        = "\nUsage: LockDevice <DH0:, DH1:, etc.> [Lock <On|Off>]\n                  [Key <Password>] [Show] [Info] [Quit]\n";
  19.  
  20.     /* Argument vector offsets. */
  21.  
  22. #define ARG_DRIVE    1
  23. #define ARG_LOCK    2
  24. #define ARG_KEY        3
  25. #define ARG_SHOW    4
  26. #define ARG_INFO    5
  27. #define ARG_QUIT    6
  28.  
  29.     /* Global lock segment. */
  30.  
  31. struct LockSeg        *LSeg;
  32.  
  33.     /* Prototypes. */
  34.  
  35. char *            FindDevice(char *DevName);
  36. struct Patch *        FindPatch(char *DeviceName);
  37. VOID            DiskChange(char *DeviceName);
  38. BYTE            DeletePatch(char *DeviceName);
  39. BYTE            DeleteLocks(VOID);
  40. BYTE            DeleteSegment(VOID);
  41. BYTE            CreateSegment(VOID);
  42. VOID            main(int argc,char **argv);
  43.  
  44.     /* FindDevice(char *DevName):
  45.      *
  46.      *    Find the device(s) associated with a device
  47.      *    driver.
  48.      */
  49.  
  50. char *
  51. FindDevice(char *DevName)
  52. {
  53.     static char             Name[257];
  54.     static struct DeviceNode    *DevInfo = NULL;
  55.     static BYTE             FirstThrough = TRUE;
  56.  
  57.     Forbid();
  58.  
  59.     if(!DevInfo)
  60.     {
  61.         DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
  62.  
  63.         if(!FirstThrough)
  64.             return(NULL);
  65.         else
  66.             FirstThrough = FALSE;
  67.     }
  68.  
  69.     while(DevInfo)
  70.     {
  71.         if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
  72.         {
  73.             struct FileSysStartupMsg *Startup = BADDR(DevInfo -> dn_Startup);
  74.  
  75.             if(!Strcmp((char *)((ULONG)BADDR(Startup -> fssm_Device) + 1),DevName))
  76.             {
  77.                 char    *Pointer;
  78.                 SHORT     i;
  79.  
  80.                 Pointer = (char *)BADDR(DevInfo -> dn_Name);
  81.  
  82.                 for(i = 0 ; i < Pointer[0] ; i++)
  83.                     Name[i] = Pointer[i + 1];
  84.  
  85.                 Name[Pointer[0]    ] = ':';
  86.                 Name[Pointer[0] + 1] = 0;
  87.  
  88.                 DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  89.  
  90.                 Permit();
  91.  
  92.                 return(Name);
  93.             }
  94.         }
  95.  
  96.         DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  97.     }
  98.  
  99.     Permit();
  100.  
  101.     return(NULL);
  102. }
  103.  
  104.     /* FindDriver(char *DevName):
  105.      *
  106.      *    Find the device driver associated with a filing device.
  107.      */
  108.  
  109. char *
  110. FindDriver(char *DevName)
  111. {
  112.     static char         Name[257];
  113.     struct DeviceNode    *DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
  114.  
  115.     Forbid();
  116.  
  117.     while(DevInfo)
  118.     {
  119.         char    *Pointer;
  120.         SHORT     i;
  121.  
  122.         Pointer = (char *)BADDR(DevInfo -> dn_Name);
  123.  
  124.         for(i = 0 ; i < Pointer[0] ; i++)
  125.             Name[i] = Pointer[i + 1];
  126.  
  127.         Name[Pointer[0]    ] = ':';
  128.         Name[Pointer[0] + 1] = 0;
  129.  
  130.         if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
  131.         {
  132.             if(!Strcmp(Name,DevName))
  133.             {
  134.                 struct FileSysStartupMsg *Startup = BADDR(DevInfo -> dn_Startup);
  135.  
  136.                 strcpy(Name,(char *)((ULONG)BADDR(Startup -> fssm_Device) + 1));
  137.  
  138.                 DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  139.  
  140.                 Permit();
  141.  
  142.                 return(Name);
  143.             }
  144.         }
  145.  
  146.         DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  147.     }
  148.  
  149.     Permit();
  150.  
  151.     return(NULL);
  152. }
  153.  
  154.     /* FindPatch(char *DeviceName):
  155.      *
  156.      *    Find the patch created for a specific filing device.
  157.      */
  158.  
  159. struct Patch *
  160. FindPatch(char *DeviceName)
  161. {
  162.     struct Patch *Patch = LSeg -> RootPatch;
  163.  
  164.     while(Patch)
  165.     {
  166.         if(!Strcmp(Patch -> UnitName,DeviceName))
  167.             return(Patch);
  168.  
  169.         Patch = Patch -> NextPatch;
  170.     }
  171.  
  172.     return(NULL);
  173. }
  174.  
  175.     /* DiskChange(char *DeviceName):
  176.      *
  177.      *    Perform a kind of diskchange event for a filing
  178.      *    device.
  179.      */
  180.  
  181. VOID
  182. DiskChange(char *DeviceName)
  183. {
  184.     struct MsgPort    *HandlerTask = DeviceProc(DeviceName);
  185.     LONG         Args[7];
  186.  
  187.     if(HandlerTask)
  188.     {
  189.         Args[0] = DOSTRUE;
  190.  
  191.         if(SendPacket(ACTION_INHIBIT,Args,HandlerTask))
  192.         {
  193.             Args[0] = DOSFALSE;
  194.  
  195.             SendPacket(ACTION_INHIBIT,Args,HandlerTask);
  196.         }
  197.     }
  198. }
  199.  
  200.     /* DeletePatch(char *DeviceName):
  201.      *
  202.      *    Unlink and remove a patch from the linked system
  203.      *    list.
  204.      */
  205.  
  206. BYTE
  207. DeletePatch(char *DeviceName)
  208. {
  209.     if(DeviceName)
  210.     {
  211.         struct Patch *TempPatch = LSeg -> RootPatch,*OldPatch = NULL;
  212.  
  213.         Disable();
  214.  
  215.         if(!Strcmp(TempPatch -> UnitName,DeviceName))
  216.         {
  217.             OldPatch = TempPatch;
  218.  
  219.             LSeg -> RootPatch = TempPatch -> NextPatch;
  220.         }
  221.         else
  222.         {
  223.             while(TempPatch)
  224.             {
  225.                 if(!Strcmp(TempPatch -> UnitName,DeviceName))
  226.                 {
  227.                     OldPatch = TempPatch;
  228.                     break;
  229.                 }
  230.  
  231.                 TempPatch = TempPatch -> NextPatch;
  232.             }
  233.  
  234.             if(!OldPatch)
  235.                 return(FALSE);
  236.             else
  237.             {
  238.                 TempPatch = LSeg -> RootPatch;
  239.  
  240.                 while(TempPatch)
  241.                 {
  242.                     if(TempPatch -> NextPatch == OldPatch)
  243.                     {
  244.                         TempPatch -> NextPatch = OldPatch -> NextPatch;
  245.                         break;
  246.                     }
  247.  
  248.                     TempPatch = TempPatch -> NextPatch;
  249.                 }
  250.             }
  251.         }
  252.  
  253.         SetFunction((struct Library *)OldPatch -> Device,DEV_BEGINIO,OldPatch -> OldBeginIO);
  254.  
  255.         Enable();
  256.  
  257.         CloseDevice(OldPatch -> Request);
  258.  
  259.         FreeMem(OldPatch -> Request,sizeof(struct IOExtTD));
  260.         FreeMem(OldPatch,sizeof(struct Patch));
  261.  
  262.         DiskChange(DeviceName);
  263.  
  264.         return(TRUE);
  265.     }
  266.  
  267.     return(FALSE);
  268. }
  269.  
  270.     /* DeleteLocks():
  271.      *
  272.      *    Delete all patches which are not protected by a
  273.      *    password.
  274.      */
  275.  
  276. BYTE
  277. DeleteLocks()
  278. {
  279.     struct Patch *Patch = LSeg -> RootPatch;
  280.  
  281.     while(Patch)
  282.     {
  283.         if(!Patch -> PassWord[0])
  284.         {
  285.             DeletePatch(Patch -> UnitName);
  286.  
  287.             Patch = LSeg -> RootPatch;
  288.             continue;
  289.         }
  290.  
  291.         Patch = Patch -> NextPatch;
  292.     }
  293.  
  294.     if(LSeg -> RootPatch)
  295.         return(FALSE);
  296.     else
  297.         return(TRUE);
  298. }
  299.  
  300.     /* DeleteSegment():
  301.      *
  302.      *    Deallocate the lock segment.
  303.      */
  304.  
  305. BYTE
  306. DeleteSegment()
  307. {
  308.     if(LSeg)
  309.     {
  310.         if(DeleteLocks())
  311.         {
  312.             LSeg -> HandShake = SIG_SHAKE;
  313.  
  314.             Signal(LSeg -> Child,SIG_QUIT);
  315.  
  316.             Wait(SIG_SHAKE);
  317.  
  318.             if(!LSeg -> Child)
  319.             {
  320.                 RemPort(&LSeg -> SignalPort);
  321.  
  322.                 FreeMem(LSeg -> SignalPort . mp_Node . ln_Name,sizeof(PORTNAME));
  323.  
  324.                 UnLoadSeg(LSeg -> HandlerSegment);
  325.  
  326.                 FreeMem(LSeg,sizeof(struct LockSeg));
  327.  
  328.                 return(TRUE);
  329.             }
  330.         }
  331.     }
  332.  
  333.     return(FALSE);
  334. }
  335.  
  336.     /* CreateSegment():
  337.      *
  338.      *    Create the lock segment.
  339.      */
  340.  
  341. BYTE
  342. CreateSegment()
  343. {
  344.     if(LSeg = (struct LockSeg *)AllocMem(sizeof(struct LockSeg),MEMF_PUBLIC | MEMF_CLEAR))
  345.     {
  346.         LSeg -> SegSize    = sizeof(struct LockSeg);
  347.         LSeg -> Father    = SysBase -> ThisTask;
  348.  
  349.         LSeg -> SignalPort . mp_Node . ln_Type    = NT_MSGPORT;
  350.         LSeg -> SignalPort . mp_Node . ln_Pri    = 1;
  351.         LSeg -> SignalPort . mp_Node . ln_Name    = (char *)AllocMem(sizeof(PORTNAME),MEMF_PUBLIC);
  352.         LSeg -> SignalPort . mp_Flags        = PA_IGNORE;
  353.  
  354.         if(LSeg -> SignalPort . mp_Node . ln_Name)
  355.         {
  356.             strcpy(LSeg -> SignalPort . mp_Node . ln_Name,PORTNAME);
  357.  
  358.             if(!(LSeg -> HandlerSegment = LoadSeg("LockDevice-Handler")))
  359.                 LSeg -> HandlerSegment = LoadSeg("L:LockDevice-Handler");
  360.  
  361.             if(LSeg -> HandlerSegment)
  362.             {
  363.                 LSeg -> HandShake = SIG_SHAKE;
  364.  
  365.                 AddPort(&LSeg -> SignalPort);
  366.  
  367.                 if(CreateProc(PORTNAME,5,LSeg -> HandlerSegment,4000))
  368.                 {
  369.                     Wait(SIG_SHAKE);
  370.  
  371.                     if(LSeg -> Child)
  372.                         return(TRUE);
  373.                 }
  374.  
  375.                 RemPort(&LSeg -> SignalPort);
  376.  
  377.                 UnLoadSeg(LSeg -> HandlerSegment);
  378.             }
  379.  
  380.             FreeMem(LSeg -> SignalPort . mp_Node . ln_Name,sizeof(PORTNAME));
  381.         }
  382.  
  383.         FreeMem(LSeg,sizeof(struct LockSeg));
  384.     }
  385.  
  386.     return(FALSE);
  387. }
  388.  
  389.     /* main(int argc,char **argv):
  390.      *
  391.      *    The main program.
  392.      */
  393.  
  394. VOID
  395. main(int argc,char **argv)
  396. {
  397.     LSeg = (struct LockSeg *)FindPort(PORTNAME);
  398.  
  399.     if(argc == 1)
  400.     {
  401.         Puts(CLI_Help);
  402.         exit(RETURN_WARN);
  403.     }
  404.  
  405.         /* Remove LockDevice? */
  406.  
  407.     if(argv[ARG_QUIT])
  408.     {
  409.         Printf("\nRemoving \33[33mLockDevice\33[31m, ");
  410.  
  411.         if(!DeleteSegment())
  412.         {
  413.             Puts("FAILED!\a\n");
  414.             exit(RETURN_FAIL);
  415.         }
  416.         else
  417.         {
  418.             Puts("\33[3mOkay.\33[0m\n");
  419.             exit(RETURN_OK);
  420.         }
  421.     }
  422.  
  423.         /* Show program info? */
  424.  
  425.     if(argv[ARG_INFO])
  426.     {
  427.         Puts("This  program  installs  patches  to prevent write access to");
  428.         Puts("data  media.   Unlike  the write protection simulated by the");
  429.         Puts("FastFileSystem,  'LockDevice' goes directly  to  the  device");
  430.         Puts("driver  itself  which  enables  it  to  reject  write/format");
  431.         Puts("requests  even  in  situations in which FastFileSystem fails");
  432.         Puts("and the disk drive is still formatted.");
  433.         Puts("   Furthermore,  'LockDevice' will work on  any  device  and");
  434.         Puts("with any filing system.\n");
  435.  
  436.         Puts("If  you  like  this  program  and  use it frequently, send a");
  437.         Puts("Share-Ware fee of at least 15 US$ or DM 20,- to:\n");
  438.  
  439.         Puts("                     Olaf Barthel, MXM");
  440.         Puts("                     Brabeckstrasse 35");
  441.         Puts("                     D-3000 Hannover 71\n");
  442.  
  443.         Puts("                Federal Republic of Germany\n");
  444.  
  445.         Puts("If you fail to pay this fee, then your conscience will haunt");
  446.         Puts("you for the rest of your life!\n");
  447.  
  448.         exit(RETURN_OK);
  449.     }
  450.  
  451.         /* Install the lock segment. */
  452.  
  453.     if(!LSeg)
  454.     {
  455.         Printf("\nInstalling \33[33m\33[1mLockDevice\33[31m\33[0m, ");
  456.  
  457.         if(!CreateSegment())
  458.         {
  459.             Puts("FAILED!\n\a");
  460.             exit(RETURN_FAIL);
  461.         }
  462.         else
  463.             Printf("\33[3mOkay.\33[0m v1.%ld © Copyright 1990 by \33[4mMXM\33[0m, \33[1mSHARE-WARE\33[0m.\n\n",REVISION);
  464.     }
  465.  
  466.         /* Install/remove a patch. */
  467.  
  468.     if(argv[ARG_DRIVE])
  469.     {
  470.             /* Remove a patch. */
  471.  
  472.         if(!Strcmp(argv[ARG_LOCK],"OFF"))
  473.         {
  474.             struct Patch *Patch;
  475.  
  476.             if(!(Patch = FindPatch(argv[ARG_DRIVE])))
  477.             {
  478.                 Printf("\33[1mLockDevice:\33[0m Unable to find locked device '%s'.\a\n",argv[ARG_DRIVE]);
  479.                 exit(RETURN_FAIL);
  480.             }
  481.  
  482.                 /* Protected by a password? */
  483.  
  484.             if(Patch -> PassWord[0])
  485.             {
  486.                     /* Password given? */
  487.  
  488.                 if(argv[ARG_KEY])
  489.                 {
  490.                         /* Does it match? */
  491.  
  492.                     if(Strcmp(argv[ARG_KEY],(char *)Patch -> PassWord))
  493.                     {
  494.                         Printf("\33[1mLockDevice:\33[0m Invalid access key for locked device '%s'.\a\n",argv[ARG_DRIVE]);
  495.                         exit(RETURN_FAIL);
  496.                     }
  497.                     else
  498.                     {
  499.                         DeletePatch(argv[ARG_DRIVE]);
  500.                         Printf("\33[1mLockDevice:\33[0m Device '%s' unlocked.\n",argv[ARG_DRIVE]);
  501.                     }
  502.                 }
  503.                 else
  504.                 {
  505.                     Printf("\33[1mLockDevice:\33[0m Device '%s' needs a key to be unlocked.\a\n",argv[ARG_DRIVE]);
  506.                     exit(RETURN_FAIL);
  507.                 }
  508.             }
  509.             else
  510.             {
  511.                 DeletePatch(argv[ARG_DRIVE]);
  512.                 Printf("\33[1mLockDevice:\33[0m Device '%s' unlocked.\n",argv[ARG_DRIVE]);
  513.             }
  514.         }
  515.         else
  516.         {
  517.                 /* Lock a device. */
  518.  
  519.             if(!Strcmp(argv[ARG_LOCK],"ON"))
  520.             {
  521.                 struct LockMsg     Message;
  522.                 char        *LockOut[40],*Pointer,*DevName;
  523.                 SHORT         NumLocked = 0;
  524.  
  525.                 if(!(DevName = FindDriver(argv[ARG_DRIVE])))
  526.                 {
  527.                     Printf("\33[1mLockDevice:\33[0m Unable to find driver for device '%s'!\a\n",argv[ARG_DRIVE]);
  528.                     exit(RETURN_FAIL);
  529.                 }
  530.  
  531.                     /* Look how many filing devices this lock will affect. */
  532.  
  533.                 while(Pointer = FindDevice(DevName))
  534.                 {
  535.                     if(!(LockOut[NumLocked] = ArpAlloc(strlen(Pointer) + 1)))
  536.                     {
  537.                         Printf("\33[1mLockDevice:\33[0m Out of memory!\a\n");
  538.                         exit(RETURN_FAIL);
  539.                     }
  540.  
  541.                     strcpy(LockOut[NumLocked++],Pointer);
  542.  
  543.                     if(NumLocked == 40)
  544.                         break;
  545.                 }
  546.  
  547.                     /* More than one device locked out? */
  548.  
  549.                 if(NumLocked > 1)
  550.                 {
  551.                     SHORT    i;
  552.                     char     Line[MaxInputBuf];
  553.  
  554.                     Printf("\33[33mWarning:\33[31m Locking '%s' will also lock the following device(s):\n\n\t\33[1m",argv[ARG_DRIVE]);
  555.  
  556.                     for(i = 0 ; i < NumLocked ; i++)
  557.                         if(Strcmp(LockOut[i],argv[ARG_DRIVE]))
  558.                             Printf("%s ",LockOut[i]);
  559.  
  560.                     Printf("\n\n\33[0mDo you wish to continue (\33[33my\33[31m/\33[33mN\33[31m) ? ");
  561.  
  562.                     ReadLine(Line);
  563.  
  564.                     if(Line[0] != 'y' && Line[0] != 'Y')
  565.                         exit(RETURN_WARN);
  566.                 }
  567.  
  568.                 Message . ExecMessage . mn_Node . ln_Type    = NT_MESSAGE;
  569.                 Message . ExecMessage . mn_Length        = sizeof(struct LockMsg);
  570.  
  571.                 Message . Success = FALSE;
  572.  
  573.                     /* Ask the handler to lock the device(s). */
  574.  
  575.                 if(Message . ExecMessage . mn_ReplyPort = (struct MsgPort *)CreatePort(NULL,0))
  576.                 {
  577.                     Message . DeviceName    = argv[ARG_DRIVE];
  578.                     Message . PassWord    = argv[ARG_KEY];
  579.  
  580.                     PutMsg(&LSeg -> SignalPort,&Message);
  581.  
  582.                     WaitPort(Message . ExecMessage . mn_ReplyPort);
  583.                     GetMsg(Message . ExecMessage . mn_ReplyPort);
  584.  
  585.                     DeletePort(Message . ExecMessage . mn_ReplyPort);
  586.                 }
  587.  
  588.                 if(!Message . Success)
  589.                 {
  590.                     Printf("\33[1mLockDevice:\33[0m Could not create lock for device '%s'.\a\n",argv[ARG_DRIVE]);
  591.                     exit(RETURN_FAIL);
  592.                 }
  593.                 else
  594.                 {
  595.                     Printf("\33[1mLockDevice:\33[0m Device '%s' locked.\n",argv[ARG_DRIVE]);
  596.                     DiskChange(argv[ARG_DRIVE]);
  597.                 }
  598.             }
  599.             else
  600.             {
  601.                 Puts(CLI_Help);
  602.                 exit(RETURN_FAIL);
  603.             }
  604.         }
  605.     }
  606.  
  607.         /* Show all locked devices. */
  608.  
  609.     if(argv[ARG_SHOW])
  610.     {
  611.         struct Patch *Patch = LSeg -> RootPatch;
  612.  
  613.         if(!Patch)
  614.         {
  615.             Puts("\33[1mLockDevice:\33[0m There are no locked devices.");
  616.             exit(RETURN_WARN);
  617.         }
  618.         else
  619.         {
  620.             char *TempName;
  621.  
  622.             Puts("Name     Driver              \n-------- --------------------");
  623.  
  624.             while(Patch)
  625.             {
  626.                 while(TempName = FindDevice(Patch -> DriverName))
  627.                 {
  628.                     if(!Strcmp(Patch -> UnitName,TempName))
  629.                         Printf("\33[33m%-8.8s\33[31m %-20.20s\n",TempName,Patch -> DriverName);
  630.                     else
  631.                         Printf("%-8.8s %-20.20s\n",TempName,Patch -> DriverName);
  632.                 }
  633.  
  634.                 Patch = Patch -> NextPatch;
  635.             }
  636.         }
  637.     }
  638.  
  639.     exit(RETURN_OK);
  640. }
  641.